/* 
 * File:   GaussianProcess.h
 * Author: hadrien
 *
 * Created on 16 avril 2012, 00:25
 */

#ifndef GAUSSIANPROCESS_H
#define	GAUSSIANPROCESS_H

template<typename IMAGEPARAMETERS>
class GaussianProcess {
public:

    typedef IMAGEPARAMETERS Params;
    typedef typename Params::features_vector_t features_vector_t;

    GaussianProcess() {
        _variances = new features_vector_t[Params::getL()];
        _means = new features_vector_t[Params::getL()];
        _aPrioriLabel = new double[Params::getL()];
        _aPosterioriLabels = new double**[Params::getWidth()];
        for (int i = 0; i < Params::getWidth(); ++i) {
            _aPosterioriLabels[i] = new double*[Params::getHeight()];
            for (int j = 0; j < Params::getHeight(); ++j) {
                _aPosterioriLabels[i][j] = new double[Params::getL()];
            }
        }
    }
    GaussianProcess(const GaussianProcess& orig);

    ~GaussianProcess() {
        delete[] _variances;
        delete[] _means;
        delete[] _aPrioriLabel;
        for (int i = 0; i < Params::getWidth(); ++i) {
            for (int j = 0; j < Params::getHeight(); ++j) {
                delete[] _aPosterioriLabels[i][j];
            }
            delete[] _aPosterioriLabels[i];
        }
        delete[] _aPosterioriLabels;
    }

    inline features_vector_t getVariance(const int& label) const {
        return _variances[label];
    }

    inline features_vector_t getMean(const int& label) const {
        return _means[label];
    }

    inline double getAPrioriLabel(const int& label) const {
        return _aPrioriLabel[label];
    }

    inline double getAPosterioriLabel(const int& i, const int& j, const int& label) const {
        return _aPosterioriLabels[i][j][label];
    }

    void setMean(const int& label, const features_vector_t& mean) {
        _means[label] = mean;
    }

    void setVariance(const int& label, const features_vector_t& variance) {
        _variances[label] = variance;
    }
    
    void setAPrioriLabel(const int& label, const double& p) const {
        _aPrioriLabel[label] = p;
    }

    void setAPosterioriLabel(const int& i, const int& j, const int& label, const double& p) const {
        _aPosterioriLabels[i][j][label] = p;
    }


private:

    features_vector_t* _means;
    features_vector_t* _variances;
    double*** _aPosterioriLabels;
    double* _aPrioriLabel;
};

#endif	/* GAUSSIANPROCESS_H */

